#*****************************************************************************************************
#* FILE: recursion.asm
#*
#* DECRIPTION
#* Write a program to find fix(i, x), where fix(i, x) is defined recursively.
#*
#* AUTHORS
#* Joe Boeding (Joe.Boeding@asu.edu) [JB]
#* Taylor Wood (Taylor.D.Wood@asu.edu) [TW]
#*
#* Computer Science & Engineering
#* CSE420 Computer Architecture I, Spring 2014
#*
#* MODIFICATION HISTORY
#* --------------------------------------------------------------------------------------------------
#****************************************************************************************************
.data
strPromptI:	.asciiz "Please enter i: \n"
strPromptX:	.asciiz "Please enter x: \n"

.text
.globl main
main:					# Start of main routine
	# initilize variables
	li	$s0, 0			# Storage for i
	li	$s1, 0			# Storage for x
	
	# retrieving i
	la 	$a0, strPromptI		# Load address of prompt 
	li	$v0, 4			# Setup the syscall print function
	syscall				# Print prompt
	li	$v0, 5			# Setup the syscall read function
	syscall				# Retrieve i
	ori	$s0, $v0, 0		# Save i

	# retrieving x
	la 	$a0, strPromptX		# Load address of prompt 
	li	$v0, 4			# Setup the syscall print function
	syscall				# Print prompt
	li	$v0, 5			# Setup the syscall read function
	syscall				# Retrieve x
	ori	$s1, $v0, 0		# Save x
	
	move	$a0, $s0		# Copy i into argument 1
	move	$a1, $s1		# Copy x into argument 2
	jal fix
	
	# ending program
	li 	$v0, 10 		# set command to stop program,
	syscall 			# end program

	

#* --------------------------------------------------------------------------------------------------
#* FUNCTION: fix(int $a0, int $a1)
#*
#* DESCRIPTION
#* 	$a0 ? (int) i
#*	$a1 - (int) x
#* 	$v0 ? (int) result
#* --------------------------------------------------------------------------------------------------
fix:
	addi 	$sp, $sp, -12		# allocate stack frame
	sw 	$ra, 8($sp)		# save return addr
	sw	$a0, 4($sp)		# save i
	sw	$a1, 0($sp)		# save x
	
	blez 	$a1, fix_i		# if (x > 0)  
		addi $a1, $a1, -1	# decrement x
		jal fix			# call fix with i, x-1
		j fix_endif		# exit if
		
	fix_i:
	blez $a0, fix_base 		# else if (i > 0)
		addi $a0, $a0, -1	# decrement i
		move $a1, $a0
		jal fix			# call fix with i-1, i-1
		addi $v0, $v0, 2	# add 2 to return value
		j fix_endif		# exit if
		
	fix_base:			# else
		li  $v0,  0		# return 0

	fix_endif:			# end if
	lw 	$ra, 8($sp)		# save return addr
	lw	$a0, 4($sp)		# save i
	lw	$a1, 0($sp)		# save x
	addi 	$sp, $sp, 12		# release stack frame
	jr	$ra

